package hotel.base.oversea.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import hotel.base.oversea.constant.CommonConstants;
import hotel.base.oversea.constant.CommonUrlConstants;
import hotel.base.oversea.constant.enums.MessageEnums;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

@Slf4j
public class SendUtils {

    /**
     * 根据类型发送钉钉消息
     * @param type
     * @return
     */
    public static String getUrlByType(Integer type){
        String retUtl = "";
        //点淼-携程处理价格房态队列-通知 || 点淼-美团异步产品变更推送-通知 || 点淼-携程/美团酒店静态变化-通知 || 点淼-飞猪处理价格/房态变化-通知 || 点淼-美团(飞猪)异步产品变更推送-通知
        if (type == MessageEnums.genre.ROOM_CHANGE_FOCUS.getCode() || type == MessageEnums.genre.PRODUCT.getCode() || type == MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode()
        ) {//|| 点淼-飞猪/美团酒店静态变化-通知
            retUtl =  CommonUrlConstants.MSG_DM_HOST;//点淼钉钉推送相关固定线 - 20201130
        }else {
            retUtl =  CommonUrlConstants.MSG_HHB_HOST;//很好办钉钉推送相关固定线 - 20201130
        }
        return retUtl;
    }

    /**
     * 发送钉钉消息通知
     */
    public static void dingMsg(String title, String data, Integer type, RestTemplate restTemplate){
        /*String accessToken = HttpClientBaseAuth.getAuthToken();
        if(null == accessToken){
            log.error("/////////////////////////////发送钉钉消息通知  accessToken null ,再次获取token");
            for (int i = 0; i < 3; i++) {
                try {
                    Thread.sleep(300);
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
                accessToken = HttpClientBaseAuth.getAuthToken();
                if(null != accessToken){
                    break;
                }
                if(i==2 && null == accessToken){
                    log.error("/////////////////////////////发送钉钉消息通知  i={} ,token还是为null",i);
                }
            }
        }*/
//        String host = CommonUrlConstants.MSG_HOST;
        String host = getUrlByType(type);

        log.info("钉钉相关信息：type= {} -- 调用的服务地址：host= {}",type,host);
        String updateUrl = host + "/message/sendMsg";
        Map params = new HashMap();
        params.put("title",title);
        params.put("message",data);
        params.put("genre",type);
        log.info("/////////////////////////////发送钉钉消息通知dingMsg  dingMsg 请求{}  :", JSON.toJSONString(params));
        //RestTemplate restTemplate = new RestTemplate();
        //发起请求
        Result result = SendUtils.post(updateUrl, JSON.toJSONString(params),restTemplate);
        //if(result.getCode() != CommonConstants.SUCCESS){
            log.info("/////////////////////////////发送钉钉消息通知dingMsg  dingMsg 返回 {},{} :", JSON.toJSONString(params), JSON.toJSONString(result));
        //}

    }

    /**
     * 发送钉钉消息通知
     */
    public static void dingMsgOrder(String title, String data, Integer type, String orderId, RestTemplate restTemplate){
        /*String accessToken = HttpClientBaseAuth.getAuthToken();
        if(null == accessToken){
            log.error("/////////////////////////////发送钉钉消息通知  accessToken null ,再次获取token");
            for (int i = 0; i < 3; i++) {
                try {
                    Thread.sleep(300);
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
                accessToken = HttpClientBaseAuth.getAuthToken();
                if(null != accessToken){
                    break;
                }
                if(i==2 && null == accessToken){
                    log.error("/////////////////////////////发送钉钉消息通知  i={} ,token还是为null",i);
                }
            }
        }*/
//        String host = CommonUrlConstants.MSG_HOST;
        String host = getUrlByType(type);
        String updateUrl = host + "/message/sendMsg";
        Map params = new HashMap();
        params.put("title",title);
        params.put("message",data);
        params.put("genre",type);
        params.put("orderId",orderId);
        log.info("/////////////////////////////发送钉钉消息通知dingMsgOrder  dingMsg 请求{}  :", JSON.toJSONString(params));
        //RestTemplate restTemplate = new RestTemplate();
        //发起请求
        Result result = SendUtils.post(updateUrl, JSON.toJSONString(params),restTemplate);
        //if(result.getCode() != CommonConstants.SUCCESS){
        log.info("/////////////////////////////发送钉钉消息通知dingMsgOrder  dingMsg 返回 {},{} :", JSON.toJSONString(params), JSON.toJSONString(result));
        //}

    }

    /**
     * 发送钉钉消息通知  消息系统不保存日志
     */
    public static void dingMsgNotLog(String title, String data, Integer type, RestTemplate restTemplate){
        /*String accessToken = HttpClientBaseAuth.getAuthToken();
        if(null == accessToken){
            log.error("/////////////////////////////发送钉钉消息通知  accessToken null ,再次获取token");
            for (int i = 0; i < 3; i++) {
                try {
                    Thread.sleep(300);
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
                accessToken = HttpClientBaseAuth.getAuthToken();
                if(null != accessToken){
                    break;
                }
                if(i==2 && null == accessToken){
                    log.error("/////////////////////////////发送钉钉消息通知  i={} ,token还是为null",i);
                }
            }
        }*/
        //        String host = CommonUrlConstants.MSG_HOST;
        String host = getUrlByType(type);
        String updateUrl = host + "/message/sendMsgNotLog";
        Map params = new HashMap();
        params.put("title",title);
        params.put("message",data);
        params.put("genre",type);
        log.info("/////////////////////////////发送钉钉消息通知dingMsgNotLog  sendMsgNotLog 请求{}  :", JSON.toJSONString(params));
        //RestTemplate restTemplate = new RestTemplate();
        //发起请求
        Result result = SendUtils.post(updateUrl, JSON.toJSONString(params),restTemplate);
        //if(result.getCode() != CommonConstants.SUCCESS){
        log.info("/////////////////////////////发送钉钉消息通知dingMsgNotLog  dingMsg 返回 {},{} :", JSON.toJSONString(params), JSON.toJSONString(result));
        //}

    }

    /**
     *
     * @author: lmf
     * @time: 2020/10/20 20:28
     * 发送钉钉消息通知  消息系统不保存日志
     */
    public static Result dingMsgNotLogByReturn(String title, String data, Integer type, RestTemplate restTemplate){
        //        String host = CommonUrlConstants.MSG_HOST;
        String host = getUrlByType(type);
        String updateUrl = host + "/message/sendMsgNotLog";
        Map params = new HashMap();
        params.put("title",title);
        params.put("message",data);
        params.put("genre",type);
        log.info("/////////////////////////////发送钉钉消息通知dingMsgNotLog  sendMsgNotLog 请求{}  :", JSON.toJSONString(params));
        //发起请求
        Result result = SendUtils.post(updateUrl, JSON.toJSONString(params),restTemplate);
        //if(result.getCode() != CommonConstants.SUCCESS){
        log.info("/////////////////////////////发送钉钉消息通知dingMsgNotLog  dingMsg 返回 {},{} :", JSON.toJSONString(params), JSON.toJSONString(result));
        return result;
    }

    public static Result post(String url, String objectJsonStrParams, RestTemplate restTemplate){
        Result response = postPush(url,objectJsonStrParams,restTemplate);
        if(response.getCode() != CommonConstants.SUCCESS && null != response.getMsg() && (response.getMsg().toString().contains("token") || response.getMsg().toString().contains("ServiceAspect"))){
            log.info(" SendUtils {} >>>>>>>>> {} post 接口返回失败，拦截异常失败，处理再次调用接口: {}",url, DateUtil.getCurrTime(),response);
            //再次调用接口
            response = SendUtils.againRequestPost(3,url,objectJsonStrParams,restTemplate);
        }
        return response;
    }

    private static Result againRequestPost(int length, String url, String paramsJson, RestTemplate restTemplate){
        Result response = null;
        for (int i = 0; i < length; i++) {
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            log.info(" SendUtils {} >>>>>>>>> {} againRequestPost 接口返回失效token或ServiceAspect异常,程序进入,三秒后重试调用接口,i={}", url, DateUtil.getCurrTime(),i);
            response = SendUtils.postPush(url,paramsJson,restTemplate);
            if(response.getCode()!= CommonConstants.SUCCESS){
                if(null != response.getMsg() && (response.getMsg().toString().contains("token") || response.getMsg().toString().contains("ServiceAspect"))){
                    log.info(" SendUtils {} >>>>>>>>> {} againRequestPost 接口返回失效token或ServiceAspect异常,程序进入,两秒后重试调用接口,i={},{}", url, DateUtil.getCurrTime(),i,response);
                }else{
                    log.info(" SendUtils {} >>>>>>>>> {} againRequestPost 接口返回失败: {},{}", url, DateUtil.getCurrTime(),response,i);
                    break;
                }
            }else{
                log.info(" SendUtils {} >>>>>>>>> {} againRequestPost 接口返回成功: {},{}", url, DateUtil.getCurrTime(),response,i);
                break;
            }
        }
        return response;
    }

    private static Result postPush(String url, String objectJsonStrParams, RestTemplate restTemplate){
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.valueOf("application/json;UTF-8"));
        HttpEntity<String> strEntity = new HttpEntity<String>(objectJsonStrParams,headers);
        /*SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(30000);// 设置超时
        requestFactory.setReadTimeout(30000);*/
        Result response = null;
        String respStr = null;
        try {
            //获取携程订单实时状态池信息
            respStr = restTemplate.postForObject(url, strEntity, String.class);
            if(ObjectUtils.isEmpty(respStr)){
                return new Result<>(" SendUtils postPush 接口异常返回null",-1);
            }
            JSONObject jsonObject  = (JSONObject) JSONObject.parse(respStr);
            if(null != jsonObject.get("code")){
                response = JSON.parseObject(respStr,Result.class);
            }else{
                Result result = new Result();
                result.setCode(-1);
                result.setMsg(respStr);
                return result;
            }
        } catch (Exception e) {
            response = new Result();
            response.setCode(-1);
            String msg = DateUtil.getNowTime()+" 发起POST请求异常 "+e.getMessage()+",url = "+url+",strEntity = "+strEntity+",respStr="+respStr;
            response.setMsg(msg);
            log.error("JobRestTemplate postPush {}",msg);
            log.error(e.getMessage(), e);
        }
        if(null == response){
            return new Result<>(" SendUtils postPush 接口异常返回null",-1);
        }
        return response;
    }

    public static Result get(String url, Map<String, Object> paramsValuesMap, RestTemplate restTemplate){
        /*if(null == paramsValuesMap || paramsValuesMap.size()==0){
            return new Result<>("paramsValuesMap 不可为空 至少存在 access_token",CommonConstants.REQUEST_ERROR);
        }*/
        Result response = getPush(url,paramsValuesMap,restTemplate);

        if(null != response.getMsg() && (response.getMsg().toString().contains("token") || response.getMsg().toString().contains("ServiceAspect"))){
            log.info(" SendUtils {} >>>>>>>>> {} get 接口返回失败，拦截异常失败，处理再次调用接口: {}",url, DateUtil.getCurrTime(),response);
            //再次调用接口
            return SendUtils.againRequestGet(3,url,paramsValuesMap,restTemplate);
        }else{
            return response;
        }


    }

    private static Result againRequestGet(int length, String url, Map<String, Object> paramsValuesMap, RestTemplate restTemplate){
        Result response = null;
        for (int i = 0; i < length; i++) {
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            log.info(" SendUtils  {} >>>>>>>>> {} againRequestGet 接口返回失效token或ServiceAspect异常,程序进入,三秒后重试调用接口,i={}", url, DateUtil.getCurrTime(),i);
            response = SendUtils.getPush(url,paramsValuesMap,restTemplate);
            if(response.getCode()!= CommonConstants.SUCCESS){
                if(null != response.getMsg() && (response.getMsg().toString().contains("token") || response.getMsg().toString().contains("ServiceAspect"))){
                    log.info(" SendUtils  {} >>>>>>>>> {}  againRequestGet 接口返回失效token或ServiceAspect异常,程序进入,两秒后重试调用接口,i={},{}", url, DateUtil.getCurrTime(),i,response);
                }else{
                    log.info(" SendUtils  {} >>>>>>>>> {}  againRequestGet 接口返回失败: {},{}", url, DateUtil.getCurrTime(),response,i);
                    break;
                }
            }else{
                log.info(" SendUtils  {} >>>>>>>>> {}  againRequestGet 接口返回成功: {},{}", url, DateUtil.getCurrTime(),response,i);
                break;
            }
        }
        return response;
    }

    private static Result getPush(String url, Map<String, Object> paramsValuesMap, RestTemplate restTemplate){
        //发起请求
        String responseStr = null;
        String sendUrl = null;
        if(null != paramsValuesMap && paramsValuesMap.size()>0){
            String paramsFormatStr = "?";//"?access_token={access_token}&countryID={countryID}&currentPageIndex={currentPageIndex}&pageSize={pageSize}";
            for (Map.Entry<String, Object> enrty:paramsValuesMap.entrySet()){
                paramsFormatStr += enrty.getKey()+"="+"{"+enrty.getKey()+"}&";
            }
            if(!paramsFormatStr.equals("?")){
                paramsFormatStr  = paramsFormatStr.substring(0,paramsFormatStr.length()-1);
            }
            sendUrl = url +paramsFormatStr;
        }else{
            sendUrl = url;
        }

        try {
            if(null != paramsValuesMap && paramsValuesMap.size()>0){
                responseStr = restTemplate.getForObject(sendUrl , String.class,paramsValuesMap);
            }else{
                responseStr = restTemplate.getForObject(sendUrl , String.class);
            }

        }catch (Exception e){
            Result response = new Result();
            response.setCode(-1);
            String msg = DateUtil.getCurrTime()+" 发起GET请求异常,url = "+sendUrl+"  paramsValuesMap = "+ JSON.toJSONString(paramsValuesMap)+","+e.getMessage();
            response.setMsg(msg);
            log.error("JobRestTemplate getPush {}",msg);
            log.error(e.getMessage(), e);
        }
        if(ObjectUtils.isEmpty(responseStr)){
            return new Result<>(" SendUtils getPush 接口异常返回null，请求参数："+ JSON.toJSONString(paramsValuesMap),-1);
        }
        Result response = null;
        try{

            JSONObject jsonObject  = (JSONObject) JSONObject.parse(responseStr);
            if(null != jsonObject.get("code")){
                response = JSON.parseObject(responseStr,Result.class);
            }else{
                Result result = new Result();
                result.setCode(-1);
                result.setMsg(responseStr);
                return result;
            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
            return new Result<>("getPush 转化接口返回异常:"+response+"  |  "+e.getMessage(),-1);
        }
        return response;
    }


    /**
     * 预警推送
     */
    public static Result sendWarnPhone(String content, Integer type, RestTemplate restTemplate){
        String host = getUrlByType(type);
        String updateUrl = host + "/message/sendVoiceToUser";
        Map params = new HashMap();
        params.put("content",content);
        params.put("genre",type);
        log.info("/////////////////////////////发送钉钉消息通知dingWarn请求{}  :", JSON.toJSONString(params));
        //发起请求
        Result result = SendUtils.post(updateUrl, JSON.toJSONString(params),restTemplate);
        //if(result.getCode() != CommonConstants.SUCCESS){
        log.info("/////////////////////////////发送钉钉消息通知dingWarn返回 {},{} :", JSON.toJSONString(params), JSON.toJSONString(result));
        return result;
    }
}
